<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>SpringBoot2学习笔记 | 恒星同学</title><meta name="keywords" content="SpringBoot"><meta name="author" content="hengxingstu"><meta name="copyright" content="hengxingstu"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="SpringBoot自动配置官方提供的自定义方式 If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your ow">
<meta property="og:type" content="article">
<meta property="og:title" content="SpringBoot2学习笔记">
<meta property="og:url" content="https://hengxingstu.gitee.io/2023/01/01/code/Springboot%E7%AC%94%E8%AE%B0/index.html">
<meta property="og:site_name" content="恒星同学">
<meta property="og:description" content="SpringBoot自动配置官方提供的自定义方式 If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your ow">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://api.vvhan.com/api/view">
<meta property="article:published_time" content="2023-01-01T13:00:00.000Z">
<meta property="article:modified_time" content="2023-01-04T02:21:25.268Z">
<meta property="article:author" content="hengxingstu">
<meta property="article:tag" content="SpringBoot">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://api.vvhan.com/api/view"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://hengxingstu.gitee.io/2023/01/01/code/Springboot%E7%AC%94%E8%AE%B0/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"prismjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'SpringBoot2学习笔记',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-01-04 10:21:25'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.1.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="https://wallpapercave.com/uwp/uwp2365506.jpeg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data is-center"><div class="data-item"><a href="/archives/"><div class="headline">文章</div><div class="length-num">36</div></a></div><div class="data-item"><a href="/tags/"><div class="headline">标签</div><div class="length-num">23</div></a></div><div class="data-item"><a href="/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 娱乐</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/gallery/"><i class="fa-fw fas fa-images"></i><span> 图库</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/contact/"><i class="fa-fw fa-fw fas fa-comment-dots"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://w.wallhaven.cc/full/x8/wallhaven-x8ye3z.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">恒星同学</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 娱乐</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/gallery/"><i class="fa-fw fas fa-images"></i><span> 图库</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/contact/"><i class="fa-fw fa-fw fas fa-comment-dots"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">SpringBoot2学习笔记</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-01-01T13:00:00.000Z" title="发表于 2023-01-01 21:00:00">2023-01-01</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-01-04T02:21:25.268Z" title="更新于 2023-01-04 10:21:25">2023-01-04</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/SpringBoot/">SpringBoot</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="SpringBoot2学习笔记"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span><span class="post-meta-separator">|</span><span class="post-meta-commentcount"><i class="far fa-comments fa-fw post-meta-icon"></i><span class="post-meta-label">评论数:</span><a href="/2023/01/01/code/Springboot%E7%AC%94%E8%AE%B0/#post-comment"><span id="twikoo-count"></span></a></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="SpringBoot"><a href="#SpringBoot" class="headerlink" title="SpringBoot"></a>SpringBoot</h1><h2 id="自动配置"><a href="#自动配置" class="headerlink" title="自动配置"></a>自动配置</h2><h3 id="官方提供的自定义方式"><a href="#官方提供的自定义方式" class="headerlink" title="官方提供的自定义方式"></a>官方提供的自定义方式</h3><blockquote>
<p>If you want to keep those Spring Boot MVC customizations and make more <a target="_blank" rel="noopener" href="https://docs.spring.io/spring/docs/5.2.9.RELEASE/spring-framework-reference/web.html#mvc">MVC customizations</a> (interceptors, formatters, view controllers, and other features), you can add your own <code>@Configuration</code> class of type <code>WebMvcConfigurer</code> but <strong>without</strong> <code>@EnableWebMvc</code>.</p>
</blockquote>
<ol>
<li><strong>不用<code>@EnableWebMvc</code>注解。使用</strong> <code>@Configuration</code> <strong>+</strong> <code>WebMvcConfigurer</code> <strong>自定义规则</strong></li>
</ol>
<blockquote>
<p>If you want to provide custom instances of <code>RequestMappingHandlerMapping</code>, <code>RequestMappingHandlerAdapter</code>, or <code>ExceptionHandlerExceptionResolver</code>, and still keep the Spring Boot MVC customizations, you can declare a bean of type <code>WebMvcRegistrations</code> and use it to provide custom instances of those components.</p>
</blockquote>
<ol start="2">
<li><strong>声明</strong> <code>WebMvcRegistrations</code> <strong>改变默认底层组件</strong></li>
</ol>
<blockquote>
<p>If you want to take complete control of Spring MVC, you can add your own <code>@Configuration</code> annotated with <code>@EnableWebMvc</code>, or alternatively add your own <code>@Configuration</code>-annotated <code>DelegatingWebMvcConfiguration</code> as described in the Javadoc of <code>@EnableWebMvc</code>.</p>
</blockquote>
<ol start="3">
<li><strong>使用</strong> <code>@EnableWebMvc</code>+<code>@Configuration</code>+<code>DelegatingWebMvcConfiguration</code> 全面接管SpringMVC</li>
</ol>
<h3 id="依赖管理"><a href="#依赖管理" class="headerlink" title="依赖管理"></a>依赖管理</h3><pre class="line-numbers language-xml" data-language="xml"><code class="language-xml">依赖管理    
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter-parent<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">></span></span>2.3.4.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">></span></span>

他的父项目是
 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>parent</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-dependencies<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">></span></span>2.3.4.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>parent</span><span class="token punctuation">></span></span>

几乎声明了所有开发中常用的依赖的版本号,“自动版本仲裁机制”
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<ul>
<li><p>对提供的默认版本不满意，可以修改默认版本号</p>
<pre class="line-numbers language-xml" data-language="xml"><code class="language-xml">1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>properties</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>mysql.version</span><span class="token punctuation">></span></span>5.1.43<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>mysql.version</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>properties</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
</li>
<li><p>springboot提供的场景启动器</p>
<pre class="line-numbers language-xml" data-language="xml"><code class="language-xml">1、见到很多 spring-boot-starter-* ： *就是某种场景
2、只要引入starter，这个场景的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4、见到的  *-spring-boot-starter： 第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>spring-boot-starter<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">></span></span>2.3.4.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">></span></span>compile<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li>
</ul>
<h2 id="容器功能"><a href="#容器功能" class="headerlink" title="容器功能"></a>容器功能</h2><h3 id="组件添加"><a href="#组件添加" class="headerlink" title="组件添加"></a>组件添加</h3><h4 id="Configuration及其对应两种加载模式"><a href="#Configuration及其对应两种加载模式" class="headerlink" title="@Configuration及其对应两种加载模式"></a>@Configuration及其对应两种加载模式</h4><p>现在有如下实例：</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">&#123;</span>
    <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
<span class="token comment">//getter、setter等方法</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>要将其作为组件添加入程序中，如果是在spring中，我们需要在xml文件中对bean进行注册，现在不需要了</p>
<p>我们直接在config包中创建Myconfig类（类名无所谓）对bean进行注册</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Configuration</span><span class="token punctuation">(</span>proxyBeanMethods <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token comment">//告诉SpringBoot这是一个配置类 == 配置文件 &amp;&amp; (proxyBeanMethods = true)是否对bean进行代理</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfig</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">//@Bean给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值，就是组件在容器中的实例</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">User</span> <span class="token function">user01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"hengxing"</span><span class="token punctuation">,</span><span class="token number">22</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>然后在启动类中写</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MainApplication</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">ConfigurableApplicationContext</span> run <span class="token operator">=</span> <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">MainApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"===========================通过容器获取==========================="</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Pet</span> tomcat01 <span class="token operator">=</span> run<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"tomcat01"</span><span class="token punctuation">,</span><span class="token class-name">Pet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Pet</span> tomcat02 <span class="token operator">=</span> run<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"tomcat01"</span><span class="token punctuation">,</span><span class="token class-name">Pet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"这两个bean相等吗？"</span> <span class="token operator">+</span> <span class="token punctuation">(</span>tomcat01 <span class="token operator">==</span> tomcat02<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token class-name">MyConfig</span> bean <span class="token operator">=</span> run<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token class-name">MyConfig</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"现在使用的对象是："</span><span class="token operator">+</span>bean<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"---------------------调用两次注册方法获取--------------------------------------"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">User</span> user01 <span class="token operator">=</span> bean<span class="token punctuation">.</span><span class="token function">user01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">User</span> user02 <span class="token operator">=</span> bean<span class="token punctuation">.</span><span class="token function">user01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"这两个bean相等吗？"</span> <span class="token operator">+</span> <span class="token punctuation">(</span>user01 <span class="token operator">==</span> user02<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>这里是控制台输出的结果：</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;分割线&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;
这两个bean相等吗？true
现在使用的对象是：com.hengxing.boot.config.MyConfig$$EnhancerBySpringCGLIB$$f289fa12@5488b5c5
---------------------调用两次注册方法--------------------------------------
这两个bean相等吗？true<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>对于结果中的信息有三点要解释：</p>
<ol>
<li><p>单实例属性</p>
<p>在启动类<code>MainApplication</code>第一部分我们获取了两次<code>tomcat01</code>，并进行比对。他们是完全一致的，说明</p>
<blockquote>
<p>配置类里面使用<code>@Bean</code>标注在方法上给容器注册组件，默认是单实例的。</p>
</blockquote>
<p>另外我们在第二部分打印出了bean的组件名，说明</p>
<blockquote>
<p>配置类本身也是组件</p>
</blockquote>
</li>
<li><p>配置类注解中的<code>proxyBeanMethods</code></p>
<p>关注bean的组件名，其中<code>EnhancerBySpringCGLIB</code>表明是被springboot增强过的对象。&#x3D;&#x3D;如何增强呢？&#x3D;&#x3D;每次你调用构造方法时，springboot会检查容器中是否有当前对象，若有就不再新建，直接使用已有的对象，即&#x3D;&#x3D;保持组件单实例属性&#x3D;&#x3D;。</p>
<p>来看第三部分，我们通过直接调用bean对象的构造方法，对比他们发现在</p>
<p><code>(proxyBeanMethods = true) </code>的情况下，也就是默认情况下，答案是<code>true</code>。而<code>(proxyBeanMethods = false) </code>的情况下，不进行代理，答案是<code>false</code>。也就是两次取出的对象都是新生成的，而不是容器中的单实例对象。</p>
<p>而对于第一部分，我们是通过<code>getbean</code>方法从容器中获取的，所以不论是否使用代理，结果都是相同的，因为容器中对象的单实例属性不会改变。</p>
<p>这里是当<code>(proxyBeanMethods = false) </code>的情况下控制台的输出</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;通过容器获取&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;
这两个bean相等吗？true
现在使用的对象是：com.hengxing.boot.config.MyConfig@30b9eadd
---------------------调用两次注册方法获取--------------------------------------
这两个bean相等吗？false<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>另外你看，这里的bean组件名就不再是增强过的对象了</p>
<p>这里的true和false分别对应两个模式：</p>
<blockquote>
<p>Full(proxyBeanMethods &#x3D; true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】</p>
<p> Lite(proxyBeanMethods &#x3D; false)【每个@Bean方法被调用多少次返回的组件都是新创建的】</p>
</blockquote>
</li>
</ol>
<h5 id="什么场景下使用这两个模式呢？"><a href="#什么场景下使用这两个模式呢？" class="headerlink" title="什么场景下使用这两个模式呢？"></a>什么场景下使用这两个模式呢？</h5><blockquote>
<ul>
<li>配置 类组件之间无依赖关系用Lite模式加速容器启动过程，减少判断<ul>
<li>配置类组件之间有依赖关系，方法会被调用得到之前单实例组件，用Full模式</li>
</ul>
</li>
</ul>
</blockquote>
<ol start="3">
<li><p>组件依赖</p>
<p>在实例类中添加Pet属性</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">&#123;</span>
    <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token class-name">Pet</span> pet<span class="token punctuation">;</span>
<span class="token comment">//getter、setter等属性，注意构造方法不要直接把pet属性写进去，要和之前一样</span>
    <span class="token keyword">public</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span> <span class="token class-name">Integer</span> age<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>修改MyConfig类中</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Bean</span>
   <span class="token keyword">public</span> <span class="token class-name">User</span> <span class="token function">user01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
       <span class="token class-name">User</span> hengxing <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"hengxing"</span><span class="token punctuation">,</span> <span class="token number">22</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
       <span class="token comment">//当开启代理时，User组件依赖了Pet组件</span>
       hengxing<span class="token punctuation">.</span><span class="token function">setPet</span><span class="token punctuation">(</span><span class="token function">tomcat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
       <span class="token keyword">return</span> hengxing<span class="token punctuation">;</span>
   <span class="token punctuation">&#125;</span>
   
<span class="token annotation punctuation">@Bean</span><span class="token punctuation">(</span><span class="token string">"tomcat01"</span><span class="token punctuation">)</span>
   <span class="token keyword">public</span> <span class="token class-name">Pet</span> <span class="token function">tomcat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
       <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Pet</span><span class="token punctuation">(</span><span class="token string">"tomcat"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>然后启动类中编写方法</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"---------------------检查依赖-----------------------------------"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token class-name">User</span> hengxing <span class="token operator">=</span> run<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"user01"</span><span class="token punctuation">,</span> <span class="token class-name">User</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token class-name">Pet</span> pet <span class="token operator">=</span> run<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"tomcat01"</span><span class="token punctuation">,</span> <span class="token class-name">Pet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"获取的对象这个bean中的Pet，是否为容器中的Pet:"</span> <span class="token operator">+</span> <span class="token punctuation">(</span>hengxing<span class="token punctuation">.</span><span class="token function">getPet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">==</span>pet<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>

<p>在这里，如果开启代理，那么答案就是true</p>
</li>
</ol>
<blockquote>
<p>你可以这样理解这个过程，<code>@Configuration</code>这个注释将你的配置类生效并告诉springboot这是个配置类，这个类现在就变成了一个容器。再使用<code>@Bean</code>向这个类中添加组件，定义一个一个Bean方法的过程，就是添加组件的过程。</p>
</blockquote>
<h4 id="Bean、-Component、-Controller、-Service、-Repository"><a href="#Bean、-Component、-Controller、-Service、-Repository" class="headerlink" title="@Bean、@Component、@Controller、@Service、@Repository"></a>@Bean、@Component、@Controller、@Service、@Repository</h4><p>这些和spring中的用法相同</p>
<h4 id="ComponentScan、-Import"><a href="#ComponentScan、-Import" class="headerlink" title="@ComponentScan、@Import"></a>@ComponentScan、@Import</h4><p><code>@ComponentScan</code>用来确定组件的扫描路径，也就是去哪里找组件的定义类。</p>
<p><code>@Import</code>用来导入外部类</p>
<blockquote>
<p>这个注解可以给容器中自动创建出所声明的类型的组件、默认组件的名字就是全类名</p>
</blockquote>
<p>例如，在配置类中添加</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span><span class="token class-name">User</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">DBHelper</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfig</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>

<p>在启动类中</p>
<pre class="line-numbers language-Java" data-language="Java"><code class="language-Java">System.out.println(&quot;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;Import检查&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&quot;);
String[] names &#x3D; run.getBeanNamesForType(User.class);&#x2F;&#x2F;获取所有User类组件的名字
for (String name : names) &#123;
    System.out.println(name);
&#125;
DBHelper bean1 &#x3D; run.getBean(DBHelper.class);
System.out.println(bean1);<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>控制台输出为</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;Import检查&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;
com.hengxing.boot.bean.User
user01
ch.qos.logback.core.db.DBHelper@5300f14a<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>

<p>第一行输出的是导入的User组件，默认是全类名</p>
<p>第二行user01是@bean方法注入的组件</p>
<p>第三行也是导入的DBHelper组件</p>
<h4 id="Conditional条件装配"><a href="#Conditional条件装配" class="headerlink" title="@Conditional条件装配"></a>@Conditional条件装配</h4><blockquote>
<p>条件装配：满足Conditional指定的条件，则进行组件注入</p>
</blockquote>
<img src="https://cdn.nlark.com/yuque/0/2020/png/1354552/1602835786727-28b6f936-62f5-4fd6-a6c5-ae690bd1e31d.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_17%2Ctext_YXRndWlndS5jb20g5bCa56GF6LC3%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10" alt="Conditional组件" style="zoom: 50%;" />

<p>我们以<code>@ConditionalOnBean</code>为例，这个注解的作用是当容器中有某个组件时加载当前组件。例如：</p>
<p>在配置类中，将user01类设置为容器中有tomcat01这个组件注册时才会注册</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfig</span> <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@ConditionalOnBean</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">"tomcat01"</span><span class="token punctuation">)</span>  <span class="token comment">//这一句</span>
    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">User</span> <span class="token function">user01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token class-name">User</span> hengxing <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"hengxing"</span><span class="token punctuation">,</span> <span class="token number">22</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        hengxing<span class="token punctuation">.</span><span class="token function">setPet</span><span class="token punctuation">(</span><span class="token function">tomcat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> hengxing<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Bean</span><span class="token punctuation">(</span><span class="token string">"tomcat01"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Pet</span> <span class="token function">tomcat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Pet</span><span class="token punctuation">(</span><span class="token string">"tomcat"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>然后在启动类中接着写</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"===================检查容器中是否有组件==================="</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"容器中有tomcat01吗？"</span><span class="token operator">+</span>run<span class="token punctuation">.</span><span class="token function">containsBean</span><span class="token punctuation">(</span><span class="token string">"tomcat01"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"容器中有user01吗？"</span><span class="token operator">+</span>run<span class="token punctuation">.</span><span class="token function">containsBean</span><span class="token punctuation">(</span><span class="token string">"user01"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>

<p>按照我们当前的理解，加了条件装配后，由于tomcat01存在，所以结果应该是两个true。我们来看一下控制台</p>
<pre class="line-numbers language-sh" data-language="sh"><code class="language-sh">&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;检查容器中是否有组件&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;
容器中有tomcat01吗？true
容器中有user01吗？false<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>

<p>怎么不对？这就引出了条件装配的另一个特性：<strong>时序性或称顺序性</strong>（官方并没有对这个有定义，我自己便于理解起的名字）。其实很好理解，根据代码顺序执行的特性，在向容器中注册user01这个组件时tomcat01这个组件还没有被注册，所以就不会被注册进容器中，所以user01不存在。而之后tomcat01根据<code>@bean</code>注释被注册进容器中，所以tomcat01存在。</p>
<p>如果我们将tomcat01放在user01前进行注册，结果就会是两个true了。</p>
<p>现在，请尝试不断调换两个组件的注册顺序和修改条件装配的语句，加深理解。</p>
<h4 id="原生配置文件引入"><a href="#原生配置文件引入" class="headerlink" title="原生配置文件引入"></a>原生配置文件引入</h4><p>我们有这样的spring配置文件，他是通过xml文件进行注入的</p>
<pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token prolog">&lt;?xml version="1.0" encoding="UTF-8"?></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans<span class="token punctuation">"</span></span>
       <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span>
       <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>haha<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>com.hengxing.boot.bean.User<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>zhangsan<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>property</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>age<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>18<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>property</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>bean</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hehe<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>com.hengxing.boot.bean.Pet<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tomcat<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>property</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>bean</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>beans</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>如果我们想在springboot中引入这样的配置，可以通过<code>@ImportResource</code>进行配置</p>
<p>在配置类中添加注释<code>@ImportResource(&quot;classpath:beans.xml&quot;)</code>，文件路径是resources文件夹。</p>
<img src="https://s2.loli.net/2023/01/01/d1ST7ghyEbRPrWV.png" alt="image-20230101114614861" style="zoom:50%;" />

<h4 id="配置绑定"><a href="#配置绑定" class="headerlink" title="配置绑定"></a>配置绑定</h4><p>如何使用springboot读取到properties文件中的内容，并且把它封装Bean中，以供随时使用；</p>
<p>配置文件中我们要有相关记录：</p>
<pre class="line-numbers language-yml" data-language="yml"><code class="language-yml">#properties.yml
car:
  brand: BYD
  color: red<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>有两种方式：</p>
<h5 id="1-Component-ConfigurationProperties"><a href="#1-Component-ConfigurationProperties" class="headerlink" title="1.@Component + @ConfigurationProperties"></a>1.@Component + @ConfigurationProperties</h5><p>生成bean类文件</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">"car"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Car</span> <span class="token punctuation">&#123;</span>
    <span class="token class-name">String</span> brand<span class="token punctuation">;</span>
    <span class="token class-name">String</span> color<span class="token punctuation">;</span>
<span class="token comment">//getter、setter等方法</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p><code>@ConfigurationProperties(prefix = &quot;car&quot;)</code>是告诉springboot配置文件中前缀为car的设置，对应文件中的各种属性。<code>Component</code>是声明为一个组件，也就是注入容器中，只有在容器中的组件，才会拥有SpringBoot提供的强大功能。</p>
<p>再写一个controller来拦截访问</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@RestController</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CarController</span> <span class="token punctuation">&#123;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token class-name">Car</span> car<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/car"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Car</span> <span class="token function">recar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> car<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p><code>@Autowired</code>可以将容器中的组件引入controller里，下面的就是简单的再页面返回信息而已。这样，你就可以在浏览器中看到返回的结果<code>&#123;&quot;brand&quot;:&quot;BYD&quot;,&quot;color&quot;:&quot;red&quot;&#125;</code></p>
<h5 id="2-EnableConfigurationProperties-ConfigurationProperties"><a href="#2-EnableConfigurationProperties-ConfigurationProperties" class="headerlink" title="2.@EnableConfigurationProperties + @ConfigurationProperties"></a>2.@EnableConfigurationProperties + @ConfigurationProperties</h5><p>类文件去掉<code>@Component</code></p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">"car"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Car</span> <span class="token punctuation">&#123;</span>
    <span class="token class-name">String</span> brand<span class="token punctuation">;</span>
    <span class="token class-name">String</span> color<span class="token punctuation">;</span>
<span class="token comment">//getter、setter等方法</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>在配置类中加入这句注释<code>@EnableConfigurationProperties(Car.class)</code></p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Configuration</span><span class="token punctuation">(</span>proxyBeanMethods <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@EnableConfigurationProperties</span><span class="token punctuation">(</span><span class="token class-name">Car</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfig</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">//内容和之前一样</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>这个注解的作用是：</p>
<ol>
<li>开启Car配置绑定功能，这样<code>@ConfigurationProperties</code>就可以发挥作用了</li>
<li>把这个Car这个组件自动注册到容器中，也就是添加到了配置类所注册的容器中</li>
</ol>
<h4 id="自动配置原理"><a href="#自动配置原理" class="headerlink" title="自动配置原理"></a>自动配置原理</h4><h5 id="自动配置类"><a href="#自动配置类" class="headerlink" title="自动配置类"></a>自动配置类</h5><p><code>@SpringBootApplication</code>我们知道他是自动为springboot注册启动类的，通过查看源码我们可以了解到，他是一个复合注解，其结构是这样的</p>
<img src="https://s2.loli.net/2023/01/01/ACP82GEIg95iadk.png" alt="image-20230101145224478" style="zoom:50%;" />

<p>其实相当于三个注解合并，</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@SpringBootConfiguration</span>
<span class="token annotation punctuation">@EnableAutoConfiguration</span>
<span class="token annotation punctuation">@ComponentScan</span><span class="token punctuation">(</span>excludeFilters <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token annotation punctuation">@Filter</span><span class="token punctuation">(</span>type <span class="token operator">=</span> <span class="token class-name">FilterType</span><span class="token punctuation">.</span>CUSTOM<span class="token punctuation">,</span> classes <span class="token operator">=</span> <span class="token class-name">TypeExcludeFilter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		<span class="token annotation punctuation">@Filter</span><span class="token punctuation">(</span>type <span class="token operator">=</span> <span class="token class-name">FilterType</span><span class="token punctuation">.</span>CUSTOM<span class="token punctuation">,</span> classes <span class="token operator">=</span> <span class="token class-name">AutoConfigurationExcludeFilter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span> <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token annotation punctuation">@interface</span> <span class="token class-name">SpringBootApplication</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>其中第一个是<code>@SpringBootConfiguration</code>，里面是@Configuration。代表当前是一个配置类。</p>
<p>第三个是<code>@ComponentScan</code>，指定扫描哪里，Spring注解；</p>
<p>第二个是重点，<code>@EnableAutoConfiguration</code></p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@AutoConfigurationPackage</span>
<span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token class-name">AutoConfigurationImportSelector</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token annotation punctuation">@interface</span> <span class="token class-name">EnableAutoConfiguration</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>

<ol>
<li><p><code>@AutoConfigurationPackage</code></p>
  <pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token class-name">AutoConfigurationPackages<span class="token punctuation">.</span>Registrar</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>  <span class="token comment">//给容器中导入一个组件</span>
<span class="token keyword">public</span> <span class="token annotation punctuation">@interface</span> <span class="token class-name">AutoConfigurationPackage</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
<span class="token comment">//利用Registrar给容器中导入一系列组件</span>
<span class="token comment">//将指定的一个包下的所有组件导入进来？MainApplication 所在包下。</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
</li>
<li><p><code>@Import(AutoConfigurationImportSelector.class)</code></p>
<blockquote>
<p>1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件<br>2、调用List<String> configurations &#x3D; getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类<br>3、利用工厂加载 Map&lt;String, List<String>&gt; loadSpringFactories(@Nullable ClassLoader classLoader)；得到所有的组件<br>4、从META-INF&#x2F;spring.factories位置来加载一个文件。<br>默认扫描我们当前系统里面所有META-INF&#x2F;spring.factories位置的文件<br>例如：spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF&#x2F;spring.factories</p>
</blockquote>
</li>
</ol>
<p><img src="https://s2.loli.net/2023/01/01/WUwE3LSshmierOg.png" alt="configurations"></p>
<p>文件里面写死了spring-boot一启动就要给容器中加载的所有配置类<br>spring-boot-autoconfigure-2.3.4.RELEASE.jar&#x2F;META-INF&#x2F;spring.factories</p>
<p>你可以打开这个包查看</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"># <span class="token class-name">Auto</span> <span class="token class-name">Configure</span>
<span class="token class-name"><span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span></span>EnableAutoConfiguration</span><span class="token operator">=</span>\
<span class="token class-name"><span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>admin<span class="token punctuation">.</span></span>SpringApplicationAdminJmxAutoConfiguration</span><span class="token punctuation">,</span>\
<span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span>
    省略很多行，一共是从<span class="token number">22</span>行到<span class="token number">148</span>行，刚好一共<span class="token number">127</span>个包
<span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span>
<span class="token class-name"><span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>webservices<span class="token punctuation">.</span>client<span class="token punctuation">.</span></span>WebServiceTemplateAutoConfiguration</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<h5 id="按需开启自动配置项"><a href="#按需开启自动配置项" class="headerlink" title="按需开启自动配置项"></a>按需开启自动配置项</h5><p>但是springboot真的加载了这么多包吗？并没有。我们在启动类中测试一下到底容器中注册了多少bean，来看控制台结果</p>
<pre class="line-numbers language-sh" data-language="sh"><code class="language-sh">&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;一共有多少bean被注册？&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;&#x3D;
132<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>

<p>如果127个包全部被注入容器中，再加上我们刚刚配置的那么多bean肯定会更多的，所以很明显这127个包中有没有被加载的。springboot如何确定这些包不被注入容器呢？</p>
<p>答案是：&#x3D;&#x3D;利用条件装配机制&#x3D;&#x3D;</p>
<p>现在我们随便打开一个springboot的组件包，能够在注释中找到类似这样的一句：</p>
<p><code>@ConditionalOnClass(&#123;JobLauncher.class, DataSource.class&#125;)</code>，也就是说，如果我们没有注册相应的类进入容器，springboot也不会加载对应的组件。很棒的想法！！！</p>
<h5 id="修改默认配置"><a href="#修改默认配置" class="headerlink" title="修改默认配置"></a>修改默认配置</h5><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Bean</span>
<span class="token annotation punctuation">@ConditionalOnBean</span><span class="token punctuation">(</span><span class="token class-name">MultipartResolver</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>  <span class="token comment">//容器中有这个类型组件</span>
<span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token class-name">DispatcherServlet</span><span class="token punctuation">.</span>MULTIPART_RESOLVER_BEAN_NAME<span class="token punctuation">)</span> <span class="token comment">//容器中没有这个名字 multipartResolver 的组件</span>
<span class="token keyword">public</span> <span class="token class-name">MultipartResolver</span> <span class="token function">multipartResolver</span><span class="token punctuation">(</span><span class="token class-name">MultipartResolver</span> resolver<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">//给@Bean标注的方法传入了对象参数，这个参数的值就会从容器中找。</span>
    <span class="token comment">//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范</span>
    <span class="token comment">// Detect if the user has created a MultipartResolver but named it incorrectly</span>
    <span class="token keyword">return</span> resolver<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
给容器中加入了文件上传解析器；<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<h5 id="总结："><a href="#总结：" class="headerlink" title="总结："></a>总结：</h5><ul>
<li><p>SpringBoot先加载所有的自动配置类  xxxxxAutoConfiguration</p>
</li>
<li><p>每个自动配置类按照条件进行生效，默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定</p>
</li>
<li><p>生效的配置类就会给容器中装配很多组件</p>
</li>
<li><p>只要容器中有这些组件，相当于这些功能就有了</p>
</li>
<li><p>定制化配置</p>
</li>
<li><ul>
<li>用户直接自己@Bean替换底层的组件</li>
<li>用户去看这个组件是获取的配置文件什么值就去修改。</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>xxxxxAutoConfiguration —&gt; 组件  —&gt;</strong> <strong>xxxxProperties里面拿值  —-&gt; application.properties</strong></p>
</blockquote>
<h4 id="开发窍门"><a href="#开发窍门" class="headerlink" title="开发窍门"></a>开发窍门</h4><h5 id="Lombok"><a href="#Lombok" class="headerlink" title="Lombok"></a>Lombok</h5><ol>
<li>简化JavaBean开发</li>
</ol>
<pre class="line-numbers language-xml" data-language="xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">></span></span>org.projectlombok<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">></span></span>lombok<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">></span></span>

idea中搜索安装lombok插件<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>然后在类中直接添加注释</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Data</span>  <span class="token comment">//声明这是数据</span>
<span class="token annotation punctuation">@ToString</span> <span class="token comment">//ToString方法</span>
<span class="token comment">//@AllArgsConstructor //全参构造</span>
<span class="token annotation punctuation">@NoArgsConstructor</span>  <span class="token comment">//无参构造</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">&#123;</span>
    <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token class-name">Integer</span> age<span class="token punctuation">;</span>
    <span class="token class-name">Pet</span> pet<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span> <span class="token class-name">Integer</span> age<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<ol start="2">
<li>简化日志开发</li>
</ol>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Slf4j</span>	<span class="token comment">//添加这个注释来进行日志开发</span>
<span class="token annotation punctuation">@RestController</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> worldController <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/w"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">world666</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        log<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"请求进来了。。。。"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//在这里输出日志</span>
        <span class="token keyword">return</span> <span class="token string">"world"</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>你会在日志中看到：</p>
<pre class="line-numbers language-sh" data-language="sh"><code class="language-sh">2023-01-01 17:36:38.994  INFO 24308 --- [nio-8888-exec-2] com.hengxing.boot.worldController        : 请求进来了。。。。<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>

<h2 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h2><p>默认使用的是application.porperties，这个东西经常出问题，而且写的东西多了非常杂乱。</p>
<p>推荐使用YAML格式</p>
<blockquote>
<p>YAML 是 “YAML Ain’t Markup Language”（YAML 不是一种标记语言）的递归缩写。在开发的这种语言时，YAML 的意思其实是：”Yet Another Markup Language”（仍是一种标记语言）。 </p>
<p>非常适合用来做以数据为中心的配置文件</p>
</blockquote>
<p>需要注意的是：</p>
<ul>
<li>字符串无需加引号，如果要加，<code>&#39; &#39; </code>与<code>&quot; &quot;</code>表示字符串内容会被 转义&#x2F;不转义</li>
</ul>
<h2 id="Web开发"><a href="#Web开发" class="headerlink" title="Web开发"></a>Web开发</h2><h3 id="静态资源访问"><a href="#静态资源访问" class="headerlink" title="静态资源访问"></a>静态资源访问</h3><p>只要静态资源放在类路径下： called <code>/static</code> (or <code>/public</code> or <code>/resources</code> or <code>/META-INF/resources</code>)</p>
<p>访问 ： 当前项目根路径&#x2F; + 静态资源名。就可以访问到静态资源</p>
<p><strong>原理： 静态映射&#x2F;</strong>**</p>
<p>请求进来，先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面</p>
<h4 id="改变静态资源访问前缀"><a href="#改变静态资源访问前缀" class="headerlink" title="改变静态资源访问前缀"></a>改变静态资源访问前缀</h4><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">mvc</span><span class="token punctuation">:</span>
    <span class="token key atrule">static-path-pattern</span><span class="token punctuation">:</span> /res/<span class="token important">**</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>

<p>这样，以后所有访问静态资源的链接必须前缀<code>/res/静态资源名</code>，例如：<code>http://localhost:8080/res/2.jpg</code></p>
<h4 id="改变静态资源存储路径"><a href="#改变静态资源存储路径" class="headerlink" title="改变静态资源存储路径"></a>改变静态资源存储路径</h4><pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">web</span><span class="token punctuation">:</span>
    <span class="token key atrule">resources</span><span class="token punctuation">:</span>
      <span class="token key atrule">static-locations</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>classpath<span class="token punctuation">:</span>/haha/<span class="token punctuation">]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>

<p>这样静态资源的路径就要在根目录下的haha文件夹下</p>
<h4 id="欢迎页支持"><a href="#欢迎页支持" class="headerlink" title="欢迎页支持"></a>欢迎页支持</h4><ol>
<li>静态资源路径下  index.html</li>
</ol>
<ul>
<li><ul>
<li>可以配置静态资源路径</li>
<li>但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问</li>
</ul>
</li>
</ul>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">spring</span><span class="token punctuation">:</span>
<span class="token comment">#  mvc:</span>
<span class="token comment">#    static-path-pattern: /res/**   这个会导致welcome page功能失效</span>

  <span class="token key atrule">resources</span><span class="token punctuation">:</span>
    <span class="token key atrule">static-locations</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>classpath<span class="token punctuation">:</span>/haha/<span class="token punctuation">]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<ol start="2">
<li>controller能处理&#x2F;index</li>
</ol>
<h4 id="静态资源配置原理"><a href="#静态资源配置原理" class="headerlink" title="静态资源配置原理"></a>静态资源配置原理</h4><ul>
<li><p>SpringBoot启动默认加载  xxxAutoConfiguration 类（自动配置类）</p>
</li>
<li><p>SpringMVC功能的自动配置类 WebMvcAutoConfiguration（在自动配置类中的web场景下），生效。下面是它的源码</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@ConditionalOnClass</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span><span class="token class-name">Servlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">DispatcherServlet</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">WebMvcConfigurer</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span><span class="token class-name">WebMvcConfigurationSupport</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>  <span class="token comment">//如果想全面接管webmvc，就自定义这个类</span>
<span class="token annotation punctuation">@AutoConfigureOrder</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2147483638</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">WebMvcAutoConfiguration</span> <span class="token punctuation">&#123;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
</li>
<li><p>给容器中配了什么？</p>
  <pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Configuration</span><span class="token punctuation">(</span>proxyBeanMethods <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>   <span class="token annotation punctuation">@Import</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span><span class="token class-name">WebMvcAutoConfiguration<span class="token punctuation">.</span>EnableWebMvcConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@EnableConfigurationProperties</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span><span class="token class-name">WebMvcProperties</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name">WebProperties</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Order</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">WebMvcAutoConfigurationAdapter</span> <span class="token keyword">implements</span> <span class="token class-name">WebMvcConfigurer</span><span class="token punctuation">,</span> <span class="token class-name">ServletContextAware</span> <span class="token punctuation">&#123;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>

<pre><code>  配置文件的相关属性和xxx进行了绑定。WebMvcProperties绑定**spring.mvc**、ResourceProperties绑定**spring.resources**
</code></pre>
</li>
</ul>
<h5 id="配置类只有一个有参构造器"><a href="#配置类只有一个有参构造器" class="headerlink" title="配置类只有一个有参构造器"></a>配置类只有一个有参构造器</h5><p>此时，有参构造器所有参数的值都会从容器中确定</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//ResourceProperties resourceProperties；获取和spring.resources绑定的所有的值的对象</span>
<span class="token comment">//WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象</span>
<span class="token comment">//ListableBeanFactory beanFactory Spring的beanFactory</span>
<span class="token comment">//HttpMessageConverters 找到所有的HttpMessageConverters</span>
<span class="token comment">//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========</span>
<span class="token comment">//DispatcherServletPath  </span>
<span class="token comment">//ServletRegistrationBean   给应用注册Servlet、Filter....</span>
	<span class="token keyword">public</span> <span class="token class-name">WebMvcAutoConfigurationAdapter</span><span class="token punctuation">(</span><span class="token class-name">ResourceProperties</span> resourceProperties<span class="token punctuation">,</span> <span class="token class-name">WebMvcProperties</span> mvcProperties<span class="token punctuation">,</span>
				<span class="token class-name">ListableBeanFactory</span> beanFactory<span class="token punctuation">,</span> <span class="token class-name">ObjectProvider</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">HttpMessageConverters</span><span class="token punctuation">></span></span> messageConvertersProvider<span class="token punctuation">,</span>
				<span class="token class-name">ObjectProvider</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ResourceHandlerRegistrationCustomizer</span><span class="token punctuation">></span></span> resourceHandlerRegistrationCustomizerProvider<span class="token punctuation">,</span>
				<span class="token class-name">ObjectProvider</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">DispatcherServletPath</span><span class="token punctuation">></span></span> dispatcherServletPath<span class="token punctuation">,</span>
				<span class="token class-name">ObjectProvider</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ServletRegistrationBean</span><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">></span><span class="token punctuation">></span></span> servletRegistrations<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
			<span class="token keyword">this</span><span class="token punctuation">.</span>resourceProperties <span class="token operator">=</span> resourceProperties<span class="token punctuation">;</span>
			<span class="token keyword">this</span><span class="token punctuation">.</span>mvcProperties <span class="token operator">=</span> mvcProperties<span class="token punctuation">;</span>
			<span class="token keyword">this</span><span class="token punctuation">.</span>beanFactory <span class="token operator">=</span> beanFactory<span class="token punctuation">;</span>
			<span class="token keyword">this</span><span class="token punctuation">.</span>messageConvertersProvider <span class="token operator">=</span> messageConvertersProvider<span class="token punctuation">;</span>
			<span class="token keyword">this</span><span class="token punctuation">.</span>resourceHandlerRegistrationCustomizer <span class="token operator">=</span> resourceHandlerRegistrationCustomizerProvider<span class="token punctuation">.</span><span class="token function">getIfAvailable</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">this</span><span class="token punctuation">.</span>dispatcherServletPath <span class="token operator">=</span> dispatcherServletPath<span class="token punctuation">;</span>
			<span class="token keyword">this</span><span class="token punctuation">.</span>servletRegistrations <span class="token operator">=</span> servletRegistrations<span class="token punctuation">;</span>
		<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<ul>
<li><p>默认静态资源配置</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addResourceHandlers</span><span class="token punctuation">(</span><span class="token class-name">ResourceHandlerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>resourceProperties<span class="token punctuation">.</span><span class="token function">isAddMappings</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                logger<span class="token punctuation">.</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string">"Default resource handling disabled"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
                <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">addResourceHandler</span><span class="token punctuation">(</span>registry<span class="token punctuation">,</span> <span class="token string">"/webjars/**"</span><span class="token punctuation">,</span> <span class="token string">"classpath:/META-INF/resources/webjars/"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//webjars的规则</span>
                <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">addResourceHandler</span><span class="token punctuation">(</span>registry<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>mvcProperties<span class="token punctuation">.</span><span class="token function">getStaticPathPattern</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>registration<span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token punctuation">&#123;</span>
                    registration<span class="token punctuation">.</span><span class="token function">addResourceLocations</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>resourceProperties<span class="token punctuation">.</span><span class="token function">getStaticLocations</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>servletContext <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                        <span class="token class-name">ServletContextResource</span> resource <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ServletContextResource</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>servletContext<span class="token punctuation">,</span> <span class="token string">"/"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        registration<span class="token punctuation">.</span><span class="token function">addResourceLocations</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Resource</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">&#123;</span>resource<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">&#125;</span>

                <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
        <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>也就是说，如果你设置add-mappings为false，就可以禁用所有静态资源规则</p>
<pre class="line-numbers language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">resources</span><span class="token punctuation">:</span>
    <span class="token key atrule">add-mappings</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>   <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li>
</ul>
<h4 id="欢迎页的处理规则"><a href="#欢迎页的处理规则" class="headerlink" title="欢迎页的处理规则"></a>欢迎页的处理规则</h4><blockquote>
<p>HandlerMapping：处理器映射。保存了每一个Handler能处理哪些请求。    </p>
</blockquote>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Bean</span>
		<span class="token keyword">public</span> <span class="token class-name">WelcomePageHandlerMapping</span> <span class="token function">welcomePageHandlerMapping</span><span class="token punctuation">(</span><span class="token class-name">ApplicationContext</span> applicationContext<span class="token punctuation">,</span>
				<span class="token class-name">FormattingConversionService</span> mvcConversionService<span class="token punctuation">,</span> <span class="token class-name">ResourceUrlProvider</span> mvcResourceUrlProvider<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
			<span class="token class-name">WelcomePageHandlerMapping</span> welcomePageHandlerMapping <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WelcomePageHandlerMapping</span><span class="token punctuation">(</span>
					<span class="token keyword">new</span> <span class="token class-name">TemplateAvailabilityProviders</span><span class="token punctuation">(</span>applicationContext<span class="token punctuation">)</span><span class="token punctuation">,</span> applicationContext<span class="token punctuation">,</span> <span class="token function">getWelcomePage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
					<span class="token keyword">this</span><span class="token punctuation">.</span>mvcProperties<span class="token punctuation">.</span><span class="token function">getStaticPathPattern</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			welcomePageHandlerMapping<span class="token punctuation">.</span><span class="token function">setInterceptors</span><span class="token punctuation">(</span><span class="token function">getInterceptors</span><span class="token punctuation">(</span>mvcConversionService<span class="token punctuation">,</span> mvcResourceUrlProvider<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			welcomePageHandlerMapping<span class="token punctuation">.</span><span class="token function">setCorsConfigurations</span><span class="token punctuation">(</span><span class="token function">getCorsConfigurations</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">return</span> welcomePageHandlerMapping<span class="token punctuation">;</span>
		<span class="token punctuation">&#125;</span>

	<span class="token class-name">WelcomePageHandlerMapping</span><span class="token punctuation">(</span><span class="token class-name">TemplateAvailabilityProviders</span> templateAvailabilityProviders<span class="token punctuation">,</span>
			<span class="token class-name">ApplicationContext</span> applicationContext<span class="token punctuation">,</span> <span class="token class-name">Optional</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Resource</span><span class="token punctuation">></span></span> welcomePage<span class="token punctuation">,</span> <span class="token class-name">String</span> staticPathPattern<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span>welcomePage<span class="token punctuation">.</span><span class="token function">isPresent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token string">"/**"</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>staticPathPattern<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token comment">//要用欢迎页功能，必须是/**</span>
			logger<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"Adding welcome page: "</span> <span class="token operator">+</span> welcomePage<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token function">setRootViewName</span><span class="token punctuation">(</span><span class="token string">"forward:index.html"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">&#125;</span>
		<span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">welcomeTemplateExists</span><span class="token punctuation">(</span>templateAvailabilityProviders<span class="token punctuation">,</span> applicationContext<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token comment">// 调用Controller  /index</span>
			logger<span class="token punctuation">.</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token string">"Adding welcome page template: index"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token function">setRootViewName</span><span class="token punctuation">(</span><span class="token string">"index"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">&#125;</span>
	<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>这里也解释了为什么我们之前在设置静态资源前缀后欢迎页会失效的原因。底端已经写死了，算是个小BUG。</p>
<h3 id="请求处理-Rest映射"><a href="#请求处理-Rest映射" class="headerlink" title="请求处理-Rest映射"></a>请求处理-Rest映射</h3><ul>
<li><p>Rest风格支持（<em>使用<strong>HTTP</strong>请求方式动词来表示对资源的操作</em>）</p>
</li>
<li><ul>
<li><em>以前：</em><em>&#x2F;getUser</em>  <em>获取用户</em>    <em>&#x2F;deleteUser</em> <em>删除用户</em>   <em>&#x2F;editUser</em>  <em>修改用户</em>      <em>&#x2F;saveUser</em> <em>保存用户</em></li>
<li><em>现在： &#x2F;user</em>    *GET-*<em>获取用户</em>    *DELETE-*<em>删除用户</em>     *PUT-*<em>修改用户</em>      *POST-*<em>保存用户</em></li>
<li>核心Filter；HiddenHttpMethodFilter<ul>
<li>由于一些历史原因，html表单只能传get、post请求，而这个方法会把我们表单传来的post请求进行解析，如果其中有隐藏信息表示它是put、或delete请求就重新封装这个请求</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><ul>
<li>用法： 表单method&#x3D;post，隐藏域 _method&#x3D;put</li>
<li>SpringBoot中手动开启</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>扩展：如何把_method 这个名字换成我们自己喜欢的。</li>
</ul>
</li>
</ul>
<p>我们先来看一下请求是如何过滤的。</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Bean</span>
<span class="token annotation punctuation">@ConditionalOnMissingBean</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span><span class="token class-name">HiddenHttpMethodFilter</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ConditionalOnProperty</span><span class="token punctuation">(</span>
        prefix <span class="token operator">=</span> <span class="token string">"spring.mvc.hiddenmethod.filter"</span><span class="token punctuation">,</span>
        name <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">"enabled"</span><span class="token punctuation">&#125;</span>
    <span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">OrderedHiddenHttpMethodFilter</span> <span class="token function">hiddenHttpMethodFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">OrderedHiddenHttpMethodFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

<span class="token comment">//OrderedHiddenHttpMethodFilter()又继承了这个下面方法</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">HiddenHttpMethodFilter</span> <span class="token keyword">extends</span> <span class="token class-name">OncePerRequestFilter</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">></span></span> ALLOWED_METHODS<span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> DEFAULT_METHOD_PARAM <span class="token operator">=</span> <span class="token string">"_method"</span><span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> methodParam <span class="token operator">=</span> <span class="token string">"_method"</span><span class="token punctuation">;</span>
    
    <span class="token comment">//这里还提供了设置参数名的方法</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMethodParam</span><span class="token punctuation">(</span><span class="token class-name">String</span> methodParam<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">Assert</span><span class="token punctuation">.</span><span class="token function">hasText</span><span class="token punctuation">(</span>methodParam<span class="token punctuation">,</span> <span class="token string">"'methodParam' must not be empty"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>methodParam <span class="token operator">=</span> methodParam<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p><code>hiddenHttpMethodFilter() </code>这是隐藏http方法过滤器，在我们没有<code>HiddenHttpMethodFilter.class</code>这个类，并且配置文件中没有配置或<code>enabled</code>值为false时会帮我们生成过滤器。其次，我们看生成方法中有<code>methodParam</code>参数，默认为<code>&quot;_method&quot;</code>。所以，我们只需要修改这个参数就行了，上面的<code>DEFAULT_METHOD_PARAM</code>是final值不可修改。</p>
<p>实现方法很简单，自己注册一个配置类，调用<code>setMethodParam</code>方法修改即可。</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Configuration</span><span class="token punctuation">(</span>proxyBeanMethods <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">WebConfig</span> <span class="token punctuation">&#123;</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">HiddenHttpMethodFilter</span> <span class="token function">hiddenHttpMethodFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token class-name">HiddenHttpMethodFilter</span> hiddenHttpMethodFilter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HiddenHttpMethodFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        hiddenHttpMethodFilter<span class="token punctuation">.</span><span class="token function">setMethodParam</span><span class="token punctuation">(</span><span class="token string">"_m"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//这里修改</span>
        <span class="token keyword">return</span> hiddenHttpMethodFilter<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<h4 id="请求处理源码分析"><a href="#请求处理源码分析" class="headerlink" title="请求处理源码分析"></a>请求处理源码分析</h4><p>现在研究一下整个请求处理过程</p>
<img src="https://s2.loli.net/2023/01/02/V16v7MRuydWP5U3.png" alt="image-20230102202410094" style="zoom: 50%;" />

<p>我们知道所有的请求都会通过<code>DispatcherServlet</code>进行拦截，所以我们打开继承树，看到继承自<code>HttpServlet</code>，那么<code>HttpServlet</code>的子类必须重写doget等一系列方法，但<code>HttpServletBean</code>里面没有，那就在<code>FrameworkServlet</code>里，最终发现了重写的doget等方法</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">protected</span> <span class="token keyword">final</span> <span class="token keyword">void</span> <span class="token function">doGet</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">ServletException</span><span class="token punctuation">,</span> <span class="token class-name">IOException</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">processRequest</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> response<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//无论是doget还是do其他，都使用了这个方法</span>
    <span class="token punctuation">&#125;</span>

<span class="token keyword">protected</span> <span class="token keyword">final</span> <span class="token keyword">void</span> <span class="token function">processRequest</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">ServletException</span><span class="token punctuation">,</span> <span class="token class-name">IOException</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">//省略一系列初始化方法</span>
    <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">doService</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> response<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IOException</span> <span class="token operator">|</span> <span class="token class-name">ServletException</span> var16<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">//省略。。。</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">//但在FrameworkServlet中它只是一个抽象类，所以子类中必然重写</span>
<span class="token keyword">protected</span> <span class="token keyword">abstract</span> <span class="token keyword">void</span> <span class="token function">doService</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>终于我们在子类<code>DispatcherServlet</code>中看到<code>doService</code>的具体实现，发现其中真正有用的是<code>doDispatch</code>做分发，接下来，重点分析这个方法</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">doDispatch</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">HttpServletRequest</span> processedRequest <span class="token operator">=</span> request<span class="token punctuation">;</span>
        <span class="token class-name">HandlerExecutionChain</span> mappedHandler <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
        <span class="token keyword">boolean</span> multipartRequestParsed <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token class-name">WebAsyncManager</span> asyncManager <span class="token operator">=</span> <span class="token class-name">WebAsyncUtils</span><span class="token punctuation">.</span><span class="token function">getAsyncManager</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//一系列初始化方法</span>

        <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
            <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
                <span class="token class-name">ModelAndView</span> mv <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
                <span class="token class-name">Object</span> dispatchException <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
                <span class="token comment">//初始化视图</span>
                <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
                    processedRequest <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">checkMultipart</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    multipartRequestParsed <span class="token operator">=</span> processedRequest <span class="token operator">!=</span> request<span class="token punctuation">;</span>
                    mappedHandler <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getHandler</span><span class="token punctuation">(</span>processedRequest<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//获取handler</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>mappedHandler <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">noHandlerFound</span><span class="token punctuation">(</span>processedRequest<span class="token punctuation">,</span> response<span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">return</span><span class="token punctuation">;</span>
                    <span class="token punctuation">&#125;</span>
。。。。。。。。。。。。。。省略。。。。。。。。。。<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>进入<code>getHandler</code>方法，大概是遍历所有<code>HandlerMapping</code></p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Nullable</span>
    <span class="token keyword">protected</span> <span class="token class-name">HandlerExecutionChain</span> <span class="token function">getHandler</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>handlerMappings <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token class-name">Iterator</span> var2 <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handlerMappings<span class="token punctuation">.</span><span class="token function">iterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token keyword">while</span><span class="token punctuation">(</span>var2<span class="token punctuation">.</span><span class="token function">hasNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token class-name">HandlerMapping</span> mapping <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">HandlerMapping</span><span class="token punctuation">)</span>var2<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token class-name">HandlerExecutionChain</span> handler <span class="token operator">=</span> mapping<span class="token punctuation">.</span><span class="token function">getHandler</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>handler <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                    <span class="token keyword">return</span> handler<span class="token punctuation">;</span>
                <span class="token punctuation">&#125;</span>
            <span class="token punctuation">&#125;</span>
        <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>打上断点分析，可以看到<strong>HandlerMapping</strong>：保存了所有<code>@RequestMapping</code>和<code>handler</code>的映射规则，打开第一个查看，内部的mappingRegistry保存了五个mapping信息</p>
<img src="https://s2.loli.net/2023/01/02/CGWiRQoI7uHsMNz.png" alt="image-20230102211025852" style="zoom:50%;" />

<p>这里和旧版略有不同，但是大致是一致的</p>
<p><img src="https://s2.loli.net/2023/01/02/yNaXgY47t8oG5he.png" alt="image-20230102211821287"></p>
<p>内部保存了对应链接的handler处理器信息，这样我们就能知道是谁来处理这个请求</p>
<p><img src="https://s2.loli.net/2023/01/03/KTEJrzV8Cqe2wul.png" alt="image-20230103092424511"></p>
<p>总结一下具体过程：</p>
<p><code>DispatcherServlet</code>拦截到请求之后，会调用<code>doService</code>开始响应，内部使用<code>doDispatch</code>做分发，决定谁来处理信息。该方法中<code>getHandler</code>保存了所有映射规则，根据我们定义好的mapping来返回<code>handler</code>。</p>
<h3 id="请求处理-常用参数注解"><a href="#请求处理-常用参数注解" class="headerlink" title="请求处理-常用参数注解"></a>请求处理-常用参数注解</h3><ul>
<li><code>@PathVariable</code> 路径变量(REST风格的变量&#x2F;id&#x2F;{id})</li>
<li><code>@RequestHeader</code> 获取请求头（不指定参数就全部获取）</li>
<li><code>@RequestParam</code> 获取请求参数（指问号后的参数，url?a&#x3D;1&amp;b&#x3D;2）</li>
<li><code>@CookieValue</code> 获取Cookie值</li>
<li><code>@RequestAttribute</code> 获取request域属性</li>
<li><code>@RequestBody</code> 获取请求体[POST]</li>
<li><code>@MatrixVariable</code> 矩阵变量</li>
<li><code>@ModelAttribute</code></li>
</ul>
<p>用例：</p>
<pre class="line-numbers language-json" data-language="json"><code class="language-json">@RequestMapping(<span class="token string">"/id/&#123;id&#125;/ower/&#123;user&#125;"</span>)
    public Map&lt;String<span class="token punctuation">,</span>Object> getCar(@PathVariable(<span class="token string">"id"</span>) Integer id<span class="token punctuation">,</span>
                                     @PathVariable(<span class="token string">"user"</span>) String user<span class="token punctuation">,</span>
                                     @PathVariable Map&lt;String<span class="token punctuation">,</span>String> pv<span class="token punctuation">,</span>
                                     @RequestHeader(<span class="token string">"User-Agent"</span>) String userAgent<span class="token punctuation">,</span>
                                     @RequestHeader Map&lt;String<span class="token punctuation">,</span>String> header<span class="token punctuation">,</span>
                                     @RequestParam(<span class="token string">"age"</span>) Integer age<span class="token punctuation">,</span>
                                     @RequestParam(<span class="token string">"inters"</span>) List&lt;String> inters<span class="token punctuation">,</span>
                                     @RequestParam MultiValueMap&lt;String<span class="token punctuation">,</span>Object> params)<span class="token punctuation">&#123;</span>
        HashMap&lt;String<span class="token punctuation">,</span> Object> map = new HashMap&lt;>();
        map.put(<span class="token string">"id"</span><span class="token punctuation">,</span>id);
        map.put(<span class="token string">"user"</span><span class="token punctuation">,</span>user);
        map.put(<span class="token string">"pv"</span><span class="token punctuation">,</span>pv);
        map.put(<span class="token string">"User-Agent"</span><span class="token punctuation">,</span>userAgent);
        map.put(<span class="token string">"header"</span><span class="token punctuation">,</span>header);
        map.put(<span class="token string">"age"</span><span class="token punctuation">,</span>age);
        map.put(<span class="token string">"inters"</span><span class="token punctuation">,</span>inters);
        map.put(<span class="token string">"params"</span><span class="token punctuation">,</span>params);
        return map;
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>得到的json</p>
<pre class="line-numbers language-json" data-language="json"><code class="language-json"><span class="token punctuation">&#123;</span>
    <span class="token property">"pv"</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
        <span class="token property">"id"</span><span class="token operator">:</span> <span class="token string">"2"</span><span class="token punctuation">,</span>
        <span class="token property">"user"</span><span class="token operator">:</span> <span class="token string">"李明"</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    <span class="token property">"inters"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token string">"basketball"</span><span class="token punctuation">,</span>
        <span class="token string">"game"</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token property">"User-Agent"</span><span class="token operator">:</span> <span class="token string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"</span><span class="token punctuation">,</span>
    <span class="token property">"header"</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
        <span class="token property">"host"</span><span class="token operator">:</span> <span class="token string">"localhost:8080"</span><span class="token punctuation">,</span>
        <span class="token property">"connection"</span><span class="token operator">:</span> <span class="token string">"keep-alive"</span><span class="token punctuation">,</span>
        <span class="token property">"sec-ch-ua"</span><span class="token operator">:</span> <span class="token string">"\"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"108\", \"Google Chrome\";v=\"108\""</span><span class="token punctuation">,</span>
        <span class="token property">"sec-ch-ua-mobile"</span><span class="token operator">:</span> <span class="token string">"?0"</span><span class="token punctuation">,</span>
        <span class="token property">"sec-ch-ua-platform"</span><span class="token operator">:</span> <span class="token string">"\"Windows\""</span><span class="token punctuation">,</span>
        <span class="token property">"upgrade-insecure-requests"</span><span class="token operator">:</span> <span class="token string">"1"</span><span class="token punctuation">,</span>
        <span class="token property">"user-agent"</span><span class="token operator">:</span> <span class="token string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"</span><span class="token punctuation">,</span>
        <span class="token property">"accept"</span><span class="token operator">:</span> <span class="token string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"</span><span class="token punctuation">,</span>
        <span class="token property">"sec-fetch-site"</span><span class="token operator">:</span> <span class="token string">"same-origin"</span><span class="token punctuation">,</span>
        <span class="token property">"sec-fetch-mode"</span><span class="token operator">:</span> <span class="token string">"navigate"</span><span class="token punctuation">,</span>
        <span class="token property">"sec-fetch-user"</span><span class="token operator">:</span> <span class="token string">"?1"</span><span class="token punctuation">,</span>
        <span class="token property">"sec-fetch-dest"</span><span class="token operator">:</span> <span class="token string">"document"</span><span class="token punctuation">,</span>
        <span class="token property">"referer"</span><span class="token operator">:</span> <span class="token string">"http://localhost:8080/"</span><span class="token punctuation">,</span>
        <span class="token property">"accept-encoding"</span><span class="token operator">:</span> <span class="token string">"gzip, deflate, br"</span><span class="token punctuation">,</span>
        <span class="token property">"accept-language"</span><span class="token operator">:</span> <span class="token string">"en,zh-CN;q=0.9,zh;q=0.8,en-CN;q=0.7"</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
    <span class="token property">"params"</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
        <span class="token property">"age"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
            <span class="token string">"18"</span>
        <span class="token punctuation">]</span><span class="token punctuation">,</span>
        <span class="token property">"inters"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
            <span class="token string">"basketball"</span><span class="token punctuation">,</span>
            <span class="token string">"game"</span>
        <span class="token punctuation">]</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    <span class="token property">"user"</span><span class="token operator">:</span> <span class="token string">"李明"</span><span class="token punctuation">,</span>
    <span class="token property">"age"</span><span class="token operator">:</span> <span class="token number">18</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<h4 id="cookie获取"><a href="#cookie获取" class="headerlink" title="cookie获取"></a>cookie获取</h4><p>cookie获取，这里的cookie值要根据浏览器中显示出来的自己修改名称，我在chrome浏览器的控制台没找到，在edge中看到了拿来用的</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">"/id/&#123;id&#125;/ower/&#123;user&#125;"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span><span class="token class-name">Object</span><span class="token punctuation">></span></span> <span class="token function">getCar</span><span class="token punctuation">(</span>                            <span class="token annotation punctuation">@CookieValue</span><span class="token punctuation">(</span><span class="token string">"Idea-b43889ba"</span><span class="token punctuation">)</span> <span class="token class-name">String</span> idea<span class="token punctuation">,</span>
                                     <span class="token annotation punctuation">@CookieValue</span><span class="token punctuation">(</span><span class="token string">"Idea-b43889ba"</span><span class="token punctuation">)</span> <span class="token class-name">Cookie</span> cookie<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">></span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"idea"</span><span class="token punctuation">,</span>idea<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>cookie<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"==>"</span><span class="token operator">+</span>cookie<span class="token punctuation">.</span><span class="token function">getValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> map<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>控制台会打印<code>Idea-b43889ba==&gt;a5a1a191-6883-4b3a-b3d7-c55ca6204e64</code></p>
<pre class="line-numbers language-json" data-language="json"><code class="language-json"><span class="token punctuation">&#123;</span><span class="token property">"idea"</span><span class="token operator">:</span><span class="token string">"a5a1a191-6883-4b3a-b3d7-c55ca6204e64"</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>

<h4 id="请求体获取"><a href="#请求体获取" class="headerlink" title="请求体获取"></a>请求体获取</h4><p>测试<code>@RequestBody</code>接收请求体</p>
<pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/save<span class="token punctuation">"</span></span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>post<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    测试@RequestBody数据<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
    用户名: <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>userName<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
    Email: <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>email<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>submit<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>提交<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@PostMapping</span><span class="token punctuation">(</span><span class="token string">"/save"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Map</span> <span class="token function">postMapping</span><span class="token punctuation">(</span><span class="token annotation punctuation">@RequestBody</span> <span class="token class-name">String</span> content<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">></span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"content"</span><span class="token punctuation">,</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> map<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<h4 id="请求域数据获取"><a href="#请求域数据获取" class="headerlink" title="请求域数据获取"></a>请求域数据获取</h4><p><code>@RequestAttribute</code>测试，之所以这么写，是因为我们要取出请求域中的数据，这个数据必须通过转发才能取得，这里<code>forward:/success</code>就是在进行转发。</p>
<ul>
<li>虽然这个注解很好用，但是个人觉得，还是通过<code>HttpServletRequest</code>直接获取整个request请求，然后调用方法更省事</li>
</ul>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Controller</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RequestController</span> <span class="token punctuation">&#123;</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/goto"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">gotoPage</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        request<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">,</span><span class="token string">"成功了。。。。"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        request<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"code"</span><span class="token punctuation">,</span><span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> <span class="token string">"forward:/success"</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/success"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Map</span> <span class="token function">success</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span>
                       <span class="token annotation punctuation">@RequestAttribute</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">)</span> <span class="token class-name">String</span> msg<span class="token punctuation">,</span>
                       <span class="token annotation punctuation">@RequestAttribute</span><span class="token punctuation">(</span><span class="token string">"code"</span><span class="token punctuation">)</span> <span class="token class-name">Integer</span> code<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>

        <span class="token class-name">Object</span> msg1 <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">></span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"reqMethod"</span><span class="token punctuation">,</span>msg1<span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"Annotation"</span><span class="token punctuation">,</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> map<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<h4 id="矩阵变量"><a href="#矩阵变量" class="headerlink" title="矩阵变量"></a>矩阵变量</h4><ul>
<li><p>什么是矩阵变量</p>
<p><code>/cars/&#123;path;low=34;brand=byd,audi,yd&#125;</code>这样用<code>;</code>隔开的变量就是矩阵变量</p>
</li>
<li><p>有什么用途</p>
<p>比如在页面开发中，cookie被禁用了，session中的内容要怎么取用？</p>
<p>例如给session存一个值<code>session.set(a,b)</code>会有一个jsessionid，统一放在cookie中，每次发送请求时携带。现在cookie被禁用我们就没办法读取session的信息了。</p>
<p>这个时候就可以用矩阵变量解决，这种行为被称为路径重写：<code>/abc;jsessionid=xxx</code></p>
</li>
</ul>
<p>会看到报错</p>
<blockquote>
<p>Resolved [org.springframework.web.bind.MissingMatrixVariableException: Required matrix variable ‘low’ for method parameter type Integer is not present]</p>
</blockquote>
<p>这是因为系统会屏蔽掉分号后的内容，所以找不到变量，我们需要把屏蔽分号这个步骤关掉</p>
<p><strong>关键点在这里</strong>，<code>webMvc</code>自动配置方法中通过实现自动配置类的接口方法<code>configurePathMatch</code></p>
  <pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">WebMvcAutoConfigurationAdapter</span> <span class="token keyword">implements</span> <span class="token class-name">WebMvcConfigurer</span><span class="token punctuation">,</span> <span class="token class-name">ServletContextAware</span> <span class="token punctuation">&#123;</span>
    
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">configurePathMatch</span><span class="token punctuation">(</span><span class="token class-name">PathMatchConfigurer</span> configurer<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">//省略不重要部分</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>servletUrlMapping<span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">singleDispatcherServlet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token class-name">UrlPathHelper</span> urlPathHelper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UrlPathHelper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            urlPathHelper<span class="token punctuation">.</span><span class="token function">setAlwaysUseFullPath</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            configurer<span class="token punctuation">.</span><span class="token function">setUrlPathHelper</span><span class="token punctuation">(</span>urlPathHelper<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>其中<code>urlPathHelper</code>类中有<code>setRemoveSemicolonContent</code>方法会移除分号</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">/**
	 * Set if ";" (semicolon) content should be stripped from the request URI.
	 * &lt;p>Default is "true".
	 */</span>
	<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setRemoveSemicolonContent</span><span class="token punctuation">(</span><span class="token keyword">boolean</span> removeSemicolonContent<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
		<span class="token function">checkReadOnly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token keyword">this</span><span class="token punctuation">.</span>removeSemicolonContent <span class="token operator">=</span> removeSemicolonContent<span class="token punctuation">;</span>
	<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<ul>
<li><p>方法一，重写一个路径匹配器，记得我们第一种自定义自动配置的方法吗</p>
<blockquote>
<p><strong>不用<code>@EnableWebMvc</code>注解。使用</strong> <code>@Configuration</code> <strong>+</strong> <code>WebMvcConfigurer</code> <strong>自定义规则</strong></p>
</blockquote>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">//所以配置类也要继承WebMvcConfigurer</span>
<span class="token annotation punctuation">@Configuration</span><span class="token punctuation">(</span>proxyBeanMethods <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">WebConfig</span> <span class="token keyword">implements</span> <span class="token class-name">WebMvcConfigurer</span> <span class="token punctuation">&#123;</span>
<span class="token comment">/*
*省略一些方法
*/</span>
<span class="token comment">//重写路径匹配器</span>
    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">configurePathMatch</span><span class="token punctuation">(</span><span class="token class-name">PathMatchConfigurer</span> configurer<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">UrlPathHelper</span> urlPathHelper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UrlPathHelper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        urlPathHelper<span class="token punctuation">.</span><span class="token function">setRemoveSemicolonContent</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        configurer<span class="token punctuation">.</span><span class="token function">setUrlPathHelper</span><span class="token punctuation">(</span>urlPathHelper<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
</li>
<li><p>方法二，不用继承，我们自己new一个<code>WebMvcConfigurer</code>，不过要记得注册为Bean</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">WebMvcConfigurer</span> <span class="token function">webMvcConfigurer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">WebMvcConfigurer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token annotation punctuation">@Override</span>
        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">configurePathMatch</span><span class="token punctuation">(</span><span class="token class-name">PathMatchConfigurer</span> configurer<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token class-name">UrlPathHelper</span> urlPathHelper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UrlPathHelper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            urlPathHelper<span class="token punctuation">.</span><span class="token function">setRemoveSemicolonContent</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            configurer<span class="token punctuation">.</span><span class="token function">setUrlPathHelper</span><span class="token punctuation">(</span>urlPathHelper<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>这里是你controller的写法，注意写在<code>@RestController</code>的方法中，因为这个东西是用json传参的</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/car/&#123;path&#125;"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Map</span> <span class="token class-name">MatrixTest</span><span class="token punctuation">(</span><span class="token annotation punctuation">@MatrixVariable</span><span class="token punctuation">(</span><span class="token string">"low"</span><span class="token punctuation">)</span> <span class="token class-name">Integer</span> low<span class="token punctuation">,</span>
                          <span class="token annotation punctuation">@MatrixVariable</span><span class="token punctuation">(</span><span class="token string">"brand"</span><span class="token punctuation">)</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">></span></span> brand<span class="token punctuation">,</span>
                          <span class="token annotation punctuation">@PathVariable</span><span class="token punctuation">(</span><span class="token string">"path"</span><span class="token punctuation">)</span> <span class="token class-name">String</span> path<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>

        <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">></span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"low"</span><span class="token punctuation">,</span>low<span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"brand"</span><span class="token punctuation">,</span>brand<span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"path"</span><span class="token punctuation">,</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> map<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>


</li>
<li><p>请求是这样的<code>http://localhost:8080/car/sell;low=29;brand=byd,yd,BMW</code></p>
</li>
<li><p>返回是这样的<code>&#123;&quot;path&quot;:&quot;sell&quot;,&quot;low&quot;:29,&quot;brand&quot;:[&quot;byd&quot;,&quot;yd&quot;,&quot;BMW&quot;]&#125;</code></p>
</li>
</ul>
<p>从这我们可以看出<code>/car/</code>后的<code>sell</code>会被看作是路径，分号后的内容会被当作矩阵变量</p>
<h4 id="一种麻烦的请求"><a href="#一种麻烦的请求" class="headerlink" title="一种麻烦的请求"></a>一种麻烦的请求</h4><p><code>/boss/1;age=20/2;age=23</code>这样的请求，当path&#x3D;1时（boos年龄）age为20，path&#x3D;2时（emp年龄）age为23</p>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/boss/&#123;bossId&#125;/&#123;empId&#125;"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token class-name">Map</span> <span class="token function">boss</span><span class="token punctuation">(</span><span class="token annotation punctuation">@MatrixVariable</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"age"</span><span class="token punctuation">,</span> pathVar <span class="token operator">=</span> <span class="token string">"empId"</span><span class="token punctuation">)</span> <span class="token class-name">Integer</span> empAge<span class="token punctuation">,</span>
<span class="token annotation punctuation">@MatrixVariable</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"age"</span><span class="token punctuation">,</span> pathVar <span class="token operator">=</span> <span class="token string">"bossId"</span><span class="token punctuation">)</span> <span class="token class-name">Integer</span> bossAge<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>

    <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">></span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"empAge"</span><span class="token punctuation">,</span>empAge<span class="token punctuation">)</span><span class="token punctuation">;</span>
    map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"bossAge"</span><span class="token punctuation">,</span>bossAge<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> map<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">//得到的结果：&#123;"bossAge":20,"empAge":23&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p><code>value = &quot;age&quot;</code>，值</p>
<p><code>pathVar = &quot;empId&quot;</code>，path变量</p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">hengxingstu</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://hengxingstu.gitee.io/2023/01/01/code/Springboot%E7%AC%94%E8%AE%B0/">https://hengxingstu.gitee.io/2023/01/01/code/Springboot%E7%AC%94%E8%AE%B0/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://hengxingstu.gitee.io" target="_blank">恒星同学</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/SpringBoot/">SpringBoot</a></div><div class="post_share"><div class="social-share" data-image="https://api.vvhan.com/api/view" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2023/01/08/code/Java%E6%95%B0%E7%BB%84/"><img class="prev-cover" src="https://api.vvhan.com/api/view" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">数组的复制、反转、查找、排序</div></div></a></div><div class="next-post pull-right"><a href="/2022/09/19/code/Angular%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/"><img class="next-cover" src="https://w.wallhaven.cc/full/6o/wallhaven-6o6orw.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">angular学习记录</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/2022/04/26/%5BYoutube%5DSpringBoot+Angular%E5%AE%9E%E6%88%98/" title="Youtube_SpringBoot+Angular实战"><img class="cover" src="https://wallpapercave.com/uwp/uwp2365506.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-04-26</div><div class="title">Youtube_SpringBoot+Angular实战</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="twikoo-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="https://wallpapercave.com/uwp/uwp2365506.jpeg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">hengxingstu</div><div class="author-info__description"></div></div><div class="card-info-data is-center"><div class="card-info-data-item"><a href="/archives/"><div class="headline">文章</div><div class="length-num">36</div></a></div><div class="card-info-data-item"><a href="/tags/"><div class="headline">标签</div><div class="length-num">23</div></a></div><div class="card-info-data-item"><a href="/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/hengxingstu"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/hengxingstu" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:hengxingstu@gmail.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">这是我的博客，欢迎和我联系，交流是最好的老师</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#SpringBoot"><span class="toc-number">1.</span> <span class="toc-text">SpringBoot</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE"><span class="toc-number">1.1.</span> <span class="toc-text">自动配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%98%E6%96%B9%E6%8F%90%E4%BE%9B%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E5%BC%8F"><span class="toc-number">1.1.1.</span> <span class="toc-text">官方提供的自定义方式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86"><span class="toc-number">1.1.2.</span> <span class="toc-text">依赖管理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%B9%E5%99%A8%E5%8A%9F%E8%83%BD"><span class="toc-number">1.2.</span> <span class="toc-text">容器功能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E6%B7%BB%E5%8A%A0"><span class="toc-number">1.2.1.</span> <span class="toc-text">组件添加</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Configuration%E5%8F%8A%E5%85%B6%E5%AF%B9%E5%BA%94%E4%B8%A4%E7%A7%8D%E5%8A%A0%E8%BD%BD%E6%A8%A1%E5%BC%8F"><span class="toc-number">1.2.1.1.</span> <span class="toc-text">@Configuration及其对应两种加载模式</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E5%9C%BA%E6%99%AF%E4%B8%8B%E4%BD%BF%E7%94%A8%E8%BF%99%E4%B8%A4%E4%B8%AA%E6%A8%A1%E5%BC%8F%E5%91%A2%EF%BC%9F"><span class="toc-number">1.2.1.1.1.</span> <span class="toc-text">什么场景下使用这两个模式呢？</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Bean%E3%80%81-Component%E3%80%81-Controller%E3%80%81-Service%E3%80%81-Repository"><span class="toc-number">1.2.1.2.</span> <span class="toc-text">@Bean、@Component、@Controller、@Service、@Repository</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ComponentScan%E3%80%81-Import"><span class="toc-number">1.2.1.3.</span> <span class="toc-text">@ComponentScan、@Import</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Conditional%E6%9D%A1%E4%BB%B6%E8%A3%85%E9%85%8D"><span class="toc-number">1.2.1.4.</span> <span class="toc-text">@Conditional条件装配</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8E%9F%E7%94%9F%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%BC%95%E5%85%A5"><span class="toc-number">1.2.1.5.</span> <span class="toc-text">原生配置文件引入</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E7%BB%91%E5%AE%9A"><span class="toc-number">1.2.1.6.</span> <span class="toc-text">配置绑定</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#1-Component-ConfigurationProperties"><span class="toc-number">1.2.1.6.1.</span> <span class="toc-text">1.@Component + @ConfigurationProperties</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#2-EnableConfigurationProperties-ConfigurationProperties"><span class="toc-number">1.2.1.6.2.</span> <span class="toc-text">2.@EnableConfigurationProperties + @ConfigurationProperties</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE%E5%8E%9F%E7%90%86"><span class="toc-number">1.2.1.7.</span> <span class="toc-text">自动配置原理</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE%E7%B1%BB"><span class="toc-number">1.2.1.7.1.</span> <span class="toc-text">自动配置类</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E6%8C%89%E9%9C%80%E5%BC%80%E5%90%AF%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9"><span class="toc-number">1.2.1.7.2.</span> <span class="toc-text">按需开启自动配置项</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E4%BF%AE%E6%94%B9%E9%BB%98%E8%AE%A4%E9%85%8D%E7%BD%AE"><span class="toc-number">1.2.1.7.3.</span> <span class="toc-text">修改默认配置</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E6%80%BB%E7%BB%93%EF%BC%9A"><span class="toc-number">1.2.1.7.4.</span> <span class="toc-text">总结：</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%BC%80%E5%8F%91%E7%AA%8D%E9%97%A8"><span class="toc-number">1.2.1.8.</span> <span class="toc-text">开发窍门</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#Lombok"><span class="toc-number">1.2.1.8.1.</span> <span class="toc-text">Lombok</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-number">1.3.</span> <span class="toc-text">配置文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Web%E5%BC%80%E5%8F%91"><span class="toc-number">1.4.</span> <span class="toc-text">Web开发</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E8%AE%BF%E9%97%AE"><span class="toc-number">1.4.1.</span> <span class="toc-text">静态资源访问</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%94%B9%E5%8F%98%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E8%AE%BF%E9%97%AE%E5%89%8D%E7%BC%80"><span class="toc-number">1.4.1.1.</span> <span class="toc-text">改变静态资源访问前缀</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%94%B9%E5%8F%98%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E5%AD%98%E5%82%A8%E8%B7%AF%E5%BE%84"><span class="toc-number">1.4.1.2.</span> <span class="toc-text">改变静态资源存储路径</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%AC%A2%E8%BF%8E%E9%A1%B5%E6%94%AF%E6%8C%81"><span class="toc-number">1.4.1.3.</span> <span class="toc-text">欢迎页支持</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E9%85%8D%E7%BD%AE%E5%8E%9F%E7%90%86"><span class="toc-number">1.4.1.4.</span> <span class="toc-text">静态资源配置原理</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E7%B1%BB%E5%8F%AA%E6%9C%89%E4%B8%80%E4%B8%AA%E6%9C%89%E5%8F%82%E6%9E%84%E9%80%A0%E5%99%A8"><span class="toc-number">1.4.1.4.1.</span> <span class="toc-text">配置类只有一个有参构造器</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%AC%A2%E8%BF%8E%E9%A1%B5%E7%9A%84%E5%A4%84%E7%90%86%E8%A7%84%E5%88%99"><span class="toc-number">1.4.1.5.</span> <span class="toc-text">欢迎页的处理规则</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%B7%E6%B1%82%E5%A4%84%E7%90%86-Rest%E6%98%A0%E5%B0%84"><span class="toc-number">1.4.2.</span> <span class="toc-text">请求处理-Rest映射</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%AF%B7%E6%B1%82%E5%A4%84%E7%90%86%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90"><span class="toc-number">1.4.2.1.</span> <span class="toc-text">请求处理源码分析</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AF%B7%E6%B1%82%E5%A4%84%E7%90%86-%E5%B8%B8%E7%94%A8%E5%8F%82%E6%95%B0%E6%B3%A8%E8%A7%A3"><span class="toc-number">1.4.3.</span> <span class="toc-text">请求处理-常用参数注解</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#cookie%E8%8E%B7%E5%8F%96"><span class="toc-number">1.4.3.1.</span> <span class="toc-text">cookie获取</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%AF%B7%E6%B1%82%E4%BD%93%E8%8E%B7%E5%8F%96"><span class="toc-number">1.4.3.2.</span> <span class="toc-text">请求体获取</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%AF%B7%E6%B1%82%E5%9F%9F%E6%95%B0%E6%8D%AE%E8%8E%B7%E5%8F%96"><span class="toc-number">1.4.3.3.</span> <span class="toc-text">请求域数据获取</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%9F%A9%E9%98%B5%E5%8F%98%E9%87%8F"><span class="toc-number">1.4.3.4.</span> <span class="toc-text">矩阵变量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%80%E7%A7%8D%E9%BA%BB%E7%83%A6%E7%9A%84%E8%AF%B7%E6%B1%82"><span class="toc-number">1.4.3.5.</span> <span class="toc-text">一种麻烦的请求</span></a></li></ol></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2023/02/21/code/springMVC%E6%96%87%E6%A1%A3/" title="Spring参考文档"><img src="https://s2.loli.net/2023/02/21/vdVhPU5RITfrXg4.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Spring参考文档"/></a><div class="content"><a class="title" href="/2023/02/21/code/springMVC%E6%96%87%E6%A1%A3/" title="Spring参考文档">Spring参考文档</a><time datetime="2023-02-21T12:26:00.000Z" title="发表于 2023-02-21 20:26:00">2023-02-21</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2023/02/16/code/SpringMVC%E7%AC%94%E8%AE%B0/" title="SpringMVC学习笔记"><img src="https://s2.loli.net/2023/02/16/N8E1LGTUnYVdmPk.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="SpringMVC学习笔记"/></a><div class="content"><a class="title" href="/2023/02/16/code/SpringMVC%E7%AC%94%E8%AE%B0/" title="SpringMVC学习笔记">SpringMVC学习笔记</a><time datetime="2023-02-16T09:06:00.000Z" title="发表于 2023-02-16 17:06:00">2023-02-16</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2023/02/16/code/Spring%E4%BA%8B%E5%8A%A1/" title="Spring学习笔记"><img src="https://s2.loli.net/2023/02/16/N8E1LGTUnYVdmPk.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Spring学习笔记"/></a><div class="content"><a class="title" href="/2023/02/16/code/Spring%E4%BA%8B%E5%8A%A1/" title="Spring学习笔记">Spring学习笔记</a><time datetime="2023-02-16T09:06:00.000Z" title="发表于 2023-02-16 17:06:00">2023-02-16</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2023/02/15/code/SpringAop%E7%AC%94%E8%AE%B0/" title="SpringAOP笔记"><img src="https://s2.loli.net/2023/02/08/jWNelFA4c7BGkTw.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="SpringAOP笔记"/></a><div class="content"><a class="title" href="/2023/02/15/code/SpringAop%E7%AC%94%E8%AE%B0/" title="SpringAOP笔记">SpringAOP笔记</a><time datetime="2023-02-15T13:00:00.000Z" title="发表于 2023-02-15 21:00:00">2023-02-15</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2023/02/12/code/Spring%E7%AC%94%E8%AE%B0/" title="Spring学习笔记"><img src="https://s2.loli.net/2023/02/12/ukqiYOMfcU4WwCJ.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Spring学习笔记"/></a><div class="content"><a class="title" href="/2023/02/12/code/Spring%E7%AC%94%E8%AE%B0/" title="Spring学习笔记">Spring学习笔记</a><time datetime="2023-02-12T05:58:00.000Z" title="发表于 2023-02-12 13:58:00">2023-02-12</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By hengxingstu</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">本地搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"><script>(()=>{
  const init = () => {
    twikoo.init(Object.assign({
      el: '#twikoo-wrap',
      envId: 'https://twikoo-hengxing.vercel.app/',
      region: '',
      onCommentLoaded: function () {
        btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.vemoji)'))
      }
    }, null))
  }

  const getCount = () => {
    twikoo.getCommentsCount({
      envId: 'https://twikoo-hengxing.vercel.app/',
      region: '',
      urls: [window.location.pathname],
      includeReply: false
    }).then(function (res) {
      document.getElementById('twikoo-count').innerText = res[0].count
    }).catch(function (err) {
      console.error(err);
    });
  }

  const runFn = () => {
    init()
    GLOBAL_CONFIG_SITE.isPost && getCount()
  }

  const loadTwikoo = () => {
    if (typeof twikoo === 'object') {
      setTimeout(runFn,0)
      return
    } 
    getScript('https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js').then(runFn)
  }

  if ('Twikoo' === 'Twikoo' || !false) {
    if (false) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
    else loadTwikoo()
  } else {
    window.loadOtherComment = () => {
      loadTwikoo()
    }
  }
})()</script></div><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = true;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/click-heart.min.js" async="async" mobile="true"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"scale":1,"hHeadPos":0.5,"vHeadPos":0.618,"jsonPath":"/live2dw/assets/haru02.model.json"},"display":{"superSample":2,"width":200,"height":400,"position":"right","hOffset":10,"vOffset":0},"mobile":{"show":false,"scale":0.5},"react":{"opacityDefault":0.7,"opacityOnHover":0.2},"dialog":{"enable":true,"hitokoto":true},"log":false});</script></body></html>